/**
* 麦卡托投影
*/
package com.imax.emap.projection
{
	import com.imax.emap.core.LatLon;
	import com.imax.emap.util.EMapUtil;
	
	import flash.geom.Point;
	
	
	public class MercatorProjection implements IProjection
	{
		
		
		private var pixelsPerLonDegree:Array;
		private var pixelsPerLonRadian:Array;
		private var bitmapOrigo:Array;
		private var numTiles:Array;
		
		public function MercatorProjection(maxZoom:int=20,tileWidth:int=256){
  			pixelsPerLonDegree = new Array();
  			pixelsPerLonRadian = new Array();
  			bitmapOrigo = new Array();
  			numTiles = new Array();
  			
			for(var d:int=0;d<maxZoom;d++)
			{
				var e:Number=tileWidth/2;
    			pixelsPerLonDegree.push(tileWidth/360);
    			pixelsPerLonRadian.push(tileWidth/(2*Math.PI));
    			bitmapOrigo.push(new Point(e,e));
    			numTiles.push(tileWidth);
    			tileWidth*=2;
   			}
		}
				
		public function fromPixelToLatLon(p:Point,zoom:int):LatLon
		{
			var e:Point=bitmapOrigo[zoom];
   			var f:Number=(p.x-e.x)/pixelsPerLonDegree[zoom];
   			var g:Number=(p.y-e.y)/-pixelsPerLonRadian[zoom];
   			var h:Number=EMapUtil.getDegreeByRadian(2*Math.atan(Math.exp(g))-Math.PI/2);
   			return new LatLon(h,f);

		}
		
		public function fromLatLonToPixel(latLon:LatLon,zoom:int):Point
		{
   			var d:Point=bitmapOrigo[zoom];
   			var e:Number=Math.round(d.x+latLon.lon * pixelsPerLonDegree[zoom]);
   			var f:Number=EMapUtil.getNumberInRange(Math.sin(EMapUtil.getRadianByDegree(latLon.lat)),-0.9999,0.9999);
   			var g:Number=Math.round(d.y+0.5*Math.log((1+f)/(1-f))*-pixelsPerLonRadian[zoom]);
   			return new Point(e,g);

		}
		
		public function getTileWidth(zoom:int):Number{
			return numTiles[zoom];
		}
		
		public function getTileHeight(zoom:int):Number{
			return numTiles[zoom];
		}
			
	}
}